package mainClasses;
import pieces.*;
import java.awt.Point;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Scanner;
public class Game {
	private static final int NUMBER_OF_CELLS = 64;					//number of cells in a chess board
	private static final int SIZE = 8;
	private static final int NUMBER_OF_QUEENS = 8;
	private boolean lost = false;									//Win or lost represented by boolean
	private Board board1;													//instant of a board
	private String name1 = "";
	private String name2 = "";
	private Queen[] queens;							//eight black queens for the purpose of the "Eight Queens" game
	private BufferedReader bufferedreader;									//for the purpose of user input
	
	/**
	 * Constructor for the Game class. It creates an instance of a board.
	 */
	public Game()													//Constructor for game
	{
		this.board1 = new Board();									//create the instance of a Board object
		queens = new Queen[8];	
	}
	
	
	/**
	 * This is the main method in the Game class.
	 * It contains the three different Games.
	 * It ask for the user inputs to select the game.
	 * It allow the player to play any one of the three games.
	 */
	public static void main(String[] args)
	{
		Game g1 = new Game();					//make an instance of the game class
		Scanner scan = new Scanner(System.in);	//for the purpose of user input
		g1.bufferedreader = new BufferedReader(new InputStreamReader(System.in)); //for the purpose of user input
		int selection = 0;					//selects the game depending on the number
		g1.board1.print();						//print the board
		
		
		//out put instruction for the user.
		System.out.println("Which game would you like to play?");
		System.out.println("1         		:-----> Eight Queens");
		System.out.println("2         		:-----> Knight's Tour");
		System.out.println("3 		  	:-----> Chess Game");
		System.out.println("More than 3		:-----> End Game");
		selection = scan.nextInt();		//get the user input
		
		//if the selection is one then play EIGHT QUEEN
		if(selection==1)
		{
			g1.eightQueenGame();
			
		//if the selection is 2 then play KNIGHT TOUR
		}if(selection==2)
		{
			g1.knightTourGame();
			
		//if it is 3 then play chess game.	
		}else if(selection==3)
		{

			g1.chessGame();
		}else
		{
			System.out.println("Hope You Enjoyed The Game");
			System.out.println("Please Play Again.");
		}
	}
	
	/**
	 * Plays the Eight Queens Game
	 */
	private void eightQueenGame()
	{
		String number = " ";
		int count = 0;					//number of queens placed
		for(int j = 0; j<SIZE; j++)
		{
			this.queens[j]=new Queen(8, 8, this.board1, "Black");
		}
		
		//instructions for the player
		System.out.println("Welcome to Eight Queens game");
		System.out.println("Type GameRules for instruction");
		System.out.println("Type QUIT to quit the game");
		
		//loop which continues until the game ended
		for(int i = 0; i<SIZE; i++)
		{
			//ask for the input
			System.out.println("You have placed " + count + " queens. You have " + (NUMBER_OF_QUEENS-count) + " left to place on the board");
			System.out.println("Enter the coordinate of this queen as 'xy'");
			//get's the input
			try
			{
				number = this.bufferedreader.readLine();
			}catch(IOException IOerror)
			{
				System.out.println("Doesn't work");
			}
			//if asked to quit then quit the game
			if(number.equals("quit")||number.equals("QUIT")||number.equals("Quit"))
			{
				System.out.println("Thank you for playing Eight Queens Game.");
				break;
			}else if(number.equals("GameRules")||number.equals("gamerules")||number.equals("GAMERULES")) //otherwise play the game and output instructions
			{
				System.out.println("This is Eight Queens Game");
				System.out.println("You have to place eight queens on the board");
				System.out.println("Each queen on the board must have a free path");
				System.out.println("Which means a queen shouldn't endanger another queen");
				System.out.println("If you succeed in placing all the eight queens on the board, YOU WIN!");
				this.board1.print();
			}
			Point p = this.getPoints(number);	//get a point representation of the string input by the user
			//Checks if point is the invalid point (9,9)
			if(p.equals(new Point(9, 9)))
			{
				i--;
				continue;
			}
			//make a queen using the point given
			Queen queen = new Queen((int)p.getY(), (int)p.getX(), this.board1, "White");
			
			//check if another queen at this location
			if(this.compareQueen(queen)==true)
			{
				System.out.println("Sorry, there's another queen at this position");
				i--;
				continue;
			}
			
			//add the queen to the board
			this.board1.add(queen);
			count++;
			this.queens[i] = queen;
			
			//if it is intercepting asker the player to put the queen else where
			if(this.eightQueen())
			{
				System.out.println("Sorry, you can't put this queen there. Try another coordinate (input : 'xy')");
				this.lost = false;
				this.board1.remove(queen.getX(), queen.getY());
				count--;
				this.queens[i]= new Queen(8, 8, this.board1, "Black");
				i--;
				continue;
			}
			
			this.board1.print(); //print the board
		}
		this.lost = true;	//set the lost to true
		
		//check if the game is won
		if(this.lost == true && count == NUMBER_OF_QUEENS)
		{
			this.lost =false;
			System.out.println("Congratulations! You Won!!");
		}
	}
	
	/**
	 * Plays the Kngith's Tour Game
	 */
	private void knightTourGame()
	{
		String input1 ="";				//used for the purpose of the input
		System.out.println("Welcome to the Knight's Tour Game");		//instruction
		boolean[][] points = new boolean[SIZE][SIZE];			//2d array of boolean represent the board and set the location true if it been visited
		//Initialise all the points to false at the beginning
		for(int i=0; i<SIZE; i++)
		{
			for(int j=0; j<SIZE; j++)
			{
				points[i][j]=false;
			}
		}
		
		//create the knight which will be used
		Knight hero = new Knight(0, 0, this.board1, "White");
		points[0][0]=true;	//set the initial location of the knight to true
		this.board1.add(hero);		//add the knight to the board
		this.board1.print();			//print the board
		
		//loop which goes on until all the points on the board is been visited by the knight.
		//or game is ended.
		for(int y=0; y<NUMBER_OF_CELLS; y++)
		{
			//ask for instruction
			System.out.println("Enter where you want to move next (input : 'xy')");
			//get the input
			try
			{
				input1 = this.bufferedreader.readLine();
			}catch(IOException IOerror)
			{
				System.out.println("Doesn't work");
			}
			//check if the user is ending the game and if it is end the game
			if(input1.equals("quit")||input1.equals("QUIT")||input1.equals("Quit"))
			{
				System.out.println("Thank you for playing Knight Tour Game.");
				break;
			}else if(input1.equals("GameRules")||input1.equals("gamerules")||input1.equals("GAMERULES")) //instruction of the game
			{
				System.out.println("Welcome to the Knight's Tour Game");
				System.out.println("You have a knight at the position (0,0)");
				System.out.println("You have to move your knight around the board");
				System.out.println("You must visit all the positions on the board");
				this.board1.print();
			}
			Point p2 = this.getPoints(input1);	//get the input(location of the knight's next move) in term of points
			int ynext = (int)p2.getY();
			int xnext = (int)p2.getX();
			if(p2.equals(new Point(9, 9)))	//check if the point is valid
			{
				y--;
				continue;
			}
			
			//check if the knight can be moved there
			if(hero.movePossible(ynext, xnext))
			{	
				//check if the place is already been moved.
				if(points[ynext][xnext])
				{
					System.out.println("Sorry, can't go there.");
					y--;
					continue;
				}
				Point prevPoint = new Point(hero.getX(), hero.getY());
				hero.moveKnight(ynext, xnext);					//if it can be moved then move it
				this.board1.getPiece((int) prevPoint.getX(), (int) prevPoint.getY()).setType("   <->   ");	//if it is moved then mark that place
				points[ynext][xnext] = true;	//if not set the new location to true
				
				//check if all the location on the board is moved
				if(this.knightTour(points))
				{
					System.out.println("Congratulations, you won the game!!");
					break;
				}
			}else	//if the move is not possible then go back to the loop
			{
				System.out.println("Can't move this Knight there, invalid move. Please try again..");
				y--;
				continue;
			}
			this.board1.print();	//print the board
		}
	}
	
	/**
	 * Plays the Ordinary Chess Game
	 */
	private void chessGame()
	{
		boolean player1 = true;	//if true then player 1 turn if not player 2's turn
		String input2 = "";	//for the input purpose
		Point select;			//which location is selected
		Point dest;				//which location is it moved
		this.board1.setUp();		//set up the board for chess game
		boolean firstturn = true;	//true if it is the first move
		boolean flip = false;		//true if the user want the board to flip after each turn
		
		
		for(int l=0; l<2; l++)
		{
			//inputs for names
			System.out.println("Enter player 1's name: ");
			try
			{
				this.name1 = this.bufferedreader.readLine();
				if(this.name1.equals(""))
				{
					this.name1 = "Player 1";
				}
			}catch(IOException IOerror)
			{
				System.out.println("Doesn't work");
			}
			
			//inputs for names
			System.out.println("Enter player 2's name: ");
			try
			{
				this.name2 = this.bufferedreader.readLine();
				if(this.name2.equals(""))
				{
					this.name2 = "Player 2";
				}
			}catch(IOException IOerror)
			{
				System.out.println("Doesn't work");
			}
			
			//inputs for flip board
			System.out.println("Players would you like to flip the board after each turn? (Yes/No)");
			try	//get the input for piece selection
			{
				input2 = this.bufferedreader.readLine();
			}catch(IOException IOerror)
			{
				System.out.println("Doesn't work");
			}
			
			//if user want the board flip
			if(input2.equals("Yes")||input2.equals("yes")||input2.equals("YES"))
			{
				flip = true;	//set the flip to true
				System.out.println("So from now on the board will flip in term's of who is playing it");
				System.out.println("At the end of each players turn, two board will be printed.");
				System.out.println("Board 1: Shows the state of the board after the move.");
				System.out.println("Board 2: Shows the state of the board after flipped.");
				break;
			}else if(input2.equals("no")||input2.equals("No")||input2.equals("NO")||input2.equals(""))
			{
				//if user doesn't want the board flip
				flip = false;
				System.out.println("Ok, board will not flip");
				break;
			}else
			{
				//if user's input is invalid
				System.out.println("Invalid input.");
				l--;
				continue;
			}
		}
		
		this.board1.print();		//print the board
		//loop goes until the game is win, lost or ended
		for(int n=0; n<2; n++)
		{
			/*
			 *  if player 1's turn.
			 * ask the player 1 for piece selection.
			 * ask the player 1 for piece destination.
			 * move the piece if can be moved.
			 */
			if(player1)
			{
				//check if the player one have any possible move if not then end the game
				if(this.noMoreMove("White"))
				{
					System.out.println(this.name1 + ": you dont have anymore move.");
					System.out.println(this.name1 + ": You Lost.");
					break;
				}
				
				//check if the king in danger if he is check if it is a check mate
				if(this.board1.getkingInDanger())
				{
					ArrayList<Point> points = this.board1.pathWay(this.findCheckingPiece("White"));
					Piece p = this.findCheckingPiece("White");
					if(!this.board1.moveAnywhereOnBoard(this.board1.wking))
					{
						if(!this.checkMateDestroyer("White", points, p))
						{
							System.out.println("Your king is trapped! CheckMate!!");
							break;
						}
						System.out.println("Your king is trapped! but there is a way out!!");
					}
				}
				
				
				
				if(firstturn)	//if it the first turn
				{
					firstturn = false; //make it no longer first turn
				}else
				{
					System.out.println(this.name1 + "'s Turn");
					this.board1.print();	//print the board
				}
				System.out.println(this.name1 + ": Select your piece (input : 'xy')");
				try	//get the input for piece selection
				{
					input2 = this.bufferedreader.readLine();
				}catch(IOException IOerror)
				{
					System.out.println("Doesn't work");
				}
				
				if(this.getPoints(input2).equals(new Point(9, 9))) //if the input is invalid
				{
					n--;
					continue;	//go back to the loop
				}
				
				//check if it is a white piece
				if(this.board1.getPiece((int)this.getPoints(input2).getY(),(int)this.getPoints(input2).getX()).getSide()=="White")
				{
					select = this.getPoints(input2);	//if it is then its ok
				}else
				{
					System.out.println(this.name1 + ": You can only select a white piece");
					n--;
					continue; //if not then go back to the loop
				}
				Piece playerone = this.board1.getPiece((int)this.getPoints(input2).getY(),(int)this.getPoints(input2).getX());
				

				//if the player 1's king in danger
				if(this.board1.getkingInDanger())
				{
					Piece piece = this.findCheckingPiece("White");
					this.board1.setkingInDanger(); //call the setkingInDanger() to set the boolean variable kingInDanger back to false
					//tell the player 1 to move the king or save the king
					System.out.println(this.name1 + ": Your king is currently in danger by " + piece.getType() + ". you must either protect or move your king");
					System.out.println(this.name1 + ": You have selected " + playerone.getType() + " please select it's destination...");
					try
					{
						input2 = this.bufferedreader.readLine();
					}catch(IOException IOerror)
					{
						System.out.println("Doesn't work");
					}
					
					//check if the input is invalid
					if(this.getPoints(input2).equals(new Point(9, 9)))
					{
						n--;
						continue;
					}
					
					//get the input for the destination
					if(this.board1.getPiece((int)select.getY(),(int)select.getX()).movePossible((int)this.getPoints(input2).getY(), (int)this.getPoints(input2).getX()))
					{
						dest = this.getPoints(input2);
					}else
					{
						System.out.println("Invalid Destination");
						n--;
						continue;
					}
					
					//move the piece
					Piece playeronedest = this.board1.getPiece((int)dest.getY(), (int)dest.getX());
					Point one = new Point(playerone.getX(),playerone.getY());
					Point two = new Point(playeronedest.getX(),playeronedest.getY());
					this.board1.getPiece((int)select.getY(),(int)select.getX()).move((int)dest.getY(), (int)dest.getX());
					this.board1.print(); //print the board
					if(this.board1.getPromotion())
					{
						this.pawnPromotion((int)dest.getY(), (int)dest.getX());
						this.board1.print();
					}
					
					/*
					 *  if the king is still in danger.
					 * 	then undo the move which was made.
					 * 	go back to the loop
					 */
					if(this.board1.getkingInDanger())
					{
						Piece piece2 = this.findCheckingPiece("White");
						System.out.println(this.name1 + ": Your move did not resolve your king problem since the king is still in danger by " + piece2.getType());
						
						playerone.changePosition((int)one.getX(), (int)one.getY());
						playeronedest.changePosition((int)two.getX(), (int)two.getY());


						this.board1.add(playeronedest);
						this.board1.add(playerone);
						this.board1.print();
						n--;
						this.board1.setkingInDanger();
						continue;
					}
					System.out.println("The king is no longer in danger");
					this.board1.print();
					n--;
					player1 = false;
					continue;
				}
				
				
				/*
				 * if the king is not in danger then ask for the destination of the piece selected above.
				 * check if the destination is movable
				 * move if true
				 * else go back to the loop ask the player 1 to select his move again
				 */
				
				System.out.println(this.name1 + ": You have selected " + this.board1.getPiece((int)this.getPoints(input2).getY(),(int)this.getPoints(input2).getX()).getType() + " please select it's destination...");
				//get the input for the destination
				try
				{
					input2 = this.bufferedreader.readLine();
				}catch(IOException IOerror)
				{
					System.out.println("Doesn't work");
				}
				if(this.getPoints(input2).equals(new Point(9, 9)))//if the input is invalid go back to the beginning of the loop
				{
					n--;
					continue;
				}
				
				//if the move is possible then move the piece
				if(this.board1.getPiece((int)select.getY(),(int)select.getX()).movePossible((int)this.getPoints(input2).getY(), (int)this.getPoints(input2).getX()))
				{
					dest = this.getPoints(input2);
				}else
				{
					System.out.println("Invalid destination");
					n--;
					continue;
				}
				
				/*
				 * if the move is made successfully
				 * check if the king in danger because of the move
				 * if it is then undo the move and player 1 have do move again
				 * if not then player 1 turn ended and player 2's turn
				 */
				Piece playeronedest2 = this.board1.getPiece((int)dest.getY(), (int)dest.getX());
				Point one = new Point(playerone.getX(), playerone.getY());
				Point two = new Point(playeronedest2.getX(), playeronedest2.getY());
				this.board1.getPiece((int)select.getY(),(int)select.getX()).move((int)dest.getY(), (int)dest.getX());
				this.board1.print();
				
				
				if(this.board1.getPromotion())
				{
					this.pawnPromotion((int)dest.getY(), (int)dest.getX());
					this.board1.print();
				}
				
				/*
				 * if the king is in danger after the move you made then undo the move and go back to the beginning.
				 */
				if(this.board1.getkingInDanger() && this.board1.whiteKingInDanger())
				{
					Piece piece = this.findCheckingPiece("White");
					System.out.println(this.name1 + ": The move you made endangered your King by " + piece.getType());
					this.board1.setkingInDanger();
					playerone.changePosition((int)one.getX(), (int) one.getY());
					playeronedest2.changePosition((int)two.getX(), (int) two.getY());

					this.board1.add(playeronedest2);
					this.board1.add(playerone);
					this.board1.print();
					n--;
					continue;
					
				}
				
				//if it is a king on move then make sure it's not going into a endangered location
				if(this.board1.getPiece((int)select.getY(),(int)select.getX()).getType().equals("   King  "))
				{
					Piece king = this.board1.getPiece((int)select.getY(),(int)select.getX());
					if(this.board1.isInDanger((int)dest.getY(), (int)dest.getX(), king.getSide()))
					{
						n--;
						continue;
					}
				}
				player1 = false;	//set the player 1 to false so the next turn is player's 2
				n--;
			}
			
			//the steps are the same for player 2 as player 1
			else
			{
				System.out.println(this.name2 + "'s Turn");
				if(this.noMoreMove("Black"))
				{
					System.out.println(this.name2 + ": you dont have anymore move.");
					break;
				}
				if(this.board1.getkingInDanger())
				{
					ArrayList<Point> points = this.board1.pathWay(this.findCheckingPiece("Black"));
					Piece p = this.findCheckingPiece("Black");
					if(!this.board1.moveAnywhereOnBoard(this.board1.bking))
					{
						if(!this.checkMateDestroyer("Black", points, p))
						{
							System.out.println("Your king is trapped! CheckMate!!");
							break;
						}
						System.out.println("Your king is trapped! but there is a way out!!");
					}
				}
				if(flip)
				{
					this.board1.printBlack();
				}
				/**
				 * if player 2's turn.
				 * ask the player 2 for piece selection.
				 * ask the player 2 for piece destination.
				 * move the piece if can be moved.
				 */
				
				System.out.println(this.name2 + ": Select your piece (input : 'xy')");
				try
				{
					input2 = this.bufferedreader.readLine();
				}catch(IOException IOerror)
				{
					System.out.println("Doesn't work");
				}
				if(this.getPoints(input2).equals(new Point(9, 9)))
				{
					n--;
					continue;
				}
				if(this.board1.getPiece((int)this.getPoints(input2).getY(),(int)this.getPoints(input2).getX()).getSide()=="Black")
				{
					select = this.getPoints(input2);
				}else
				{
					System.out.println(this.name2 + ": You can only select a black piece");
					n--;
					continue;
				}
				Piece playertwo = this.board1.getPiece((int)this.getPoints(input2).getY(),(int)this.getPoints(input2).getX());
				
				
				
				
				
				if(this.board1.getkingInDanger())
				{
					
					Piece piece = this.findCheckingPiece("Black");
					this.board1.setkingInDanger();
					System.out.println(this.name2 + ": Your king is currently in danger by " +this.name1 + "'s " + piece.getSide() + ". you must either protect your king or move your king.");
					System.out.println(this.name2 + ": You have selected " + playertwo.getType() + " please select it's destination...");
					try
					{
						input2 = this.bufferedreader.readLine();
					}catch(IOException IOerror)
					{
						System.out.println("Doesn't work");
					}
					if(this.getPoints(input2).equals(new Point(9, 9)))
					{
						n--;
						continue;
					}
					if(this.board1.getPiece((int)select.getY(),(int)select.getX()).movePossible((int)this.getPoints(input2).getY(), (int)this.getPoints(input2).getX()))
					{
						dest = this.getPoints(input2);
					}else
					{
						System.out.println("Invalid Destination");
						n--;
						continue;
					}
					Piece playertwodest = this.board1.getPiece((int)dest.getY(), (int)dest.getX());
					Point one = new Point(playertwo.getX(), playertwo.getY());
					Point two = new Point(playertwodest.getX(), playertwodest.getY());
					this.board1.getPiece((int)select.getY(),(int)select.getX()).move((int)dest.getY(), (int)dest.getX());
					if(flip)
					{
						this.board1.printBlack();
					}else
					{
						this.board1.print();
					}
					if(this.board1.getPromotion())
					{
						this.pawnPromotion((int)dest.getY(), (int)dest.getX());
						if(flip)
						{
							this.board1.printBlack();
						}else
						{
							this.board1.print();
						}
					}
					if(this.board1.getPromotion())
					{
						this.pawnPromotion((int)dest.getY(), (int)dest.getX());
						if(flip)
						{
							this.board1.printBlack();
						}else
						{
							this.board1.print();
						}
					}
					if(this.board1.getkingInDanger())
					{
						Piece piece2 = this.findCheckingPiece("Black");
						System.out.println(this.name2 + ": The move you have made didn't resolve your king problem since the king is still in danger by " + piece2.getType());
						playertwo.changePosition((int)one.getX(), (int)one.getY());
						playertwodest.changePosition((int)two.getX(), (int)two.getY());

						this.board1.add(playertwodest);
						this.board1.add(playertwo);
						if(flip)
						{
							this.board1.printBlack();
						}else
						{
							this.board1.print();
						}
						n--;
						this.board1.setkingInDanger();
						continue;
					}
					System.out.println("Your king is no longer in danger");
					if(flip)
					{
						this.board1.printBlack();
					}else
					{
						this.board1.print();
					}
					n--;
					player1 = true;
					this.board1.setkingInDanger();
					continue;
				}
				
				System.out.println(this.name2 + ": You have selected " + this.board1.getPiece((int)this.getPoints(input2).getY(),(int)this.getPoints(input2).getX()).getType() + ". Please select a destination.");
				try
				{
					input2 = this.bufferedreader.readLine();
				}catch(IOException IOerror)
				{
					System.out.println("Doesn't Work");
				}
				if(this.getPoints(input2).equals(new Point(9, 9)))
				{
					System.out.println("Invalid Input");
					n--;
					continue;
				}
				if(this.board1.getPiece((int)select.getY(),(int)select.getX()).movePossible((int)this.getPoints(input2).getY(), (int)this.getPoints(input2).getX()))
				{
					dest = this.getPoints(input2);
				}else
				{
					System.out.println("Invalid Destination");
					n--;
					continue;
				}
				Piece playertwodest2 = this.board1.getPiece((int)dest.getY(), (int)dest.getX());
				Point one = new Point((int) playertwo.getX(), (int) playertwo.getY());
				Point two = new Point((int) playertwodest2.getX(), (int) playertwodest2.getY());
				this.board1.getPiece((int)select.getY(),(int)select.getX()).move((int)dest.getY(), (int)dest.getX());
				if(flip)
				{
					this.board1.printBlack();
				}else
				{
					this.board1.print();
				}
				if(this.board1.getPromotion())
				{
					this.pawnPromotion((int)dest.getY(), (int)dest.getX());
					if(flip)
					{
						this.board1.printBlack();
					}else
					{
						this.board1.print();
					}
				}

				
				if(this.board1.getkingInDanger() && !this.board1.whiteKingInDanger())
				{
					Piece piece = this.findCheckingPiece("Black");
					System.out.println(this.name2 + ": The move you made endangered your King by enemie's " + piece.getType());
					this.board1.setkingInDanger();
					playertwo.changePosition((int)one.getX(), (int)one.getY());
					playertwodest2.changePosition((int)two.getX(), (int)two.getY());
					this.board1.add(playertwodest2);
					this.board1.add(playertwo);
					if(flip)
					{
						
						this.board1.printBlack();
					}else
					{
						this.board1.print();
					}
					n--;
					continue;
					
				}
				if(this.board1.getPiece((int)select.getY(),(int)select.getX()).getType().equals("BK-->King"))
				{
					Piece king = this.board1.getPiece((int)select.getY(),(int)select.getX());
					if(this.board1.isInDanger((int)dest.getY(), (int)dest.getX(), king.getSide()))
					{
						n--;
						continue;
					}
				}
				player1 = true;
				n--;
			}
		}
	}
	/**
	 * This method checks if a possible checkmate can be avoided by moving a piece to block the check
	 * 
	 * 
	 * @param side - Current side of the player (White/Black)
	 * @param points - array of points which represent the pathway from the king to the piece which is checking it.
	 * @param p - The enemie's piece
	 * @return boolean value of true if the enemy piece can be blocked or killed, false if no possible block or kill
	 */
	public boolean checkMateDestroyer(String side, ArrayList<Point> points, Piece p)
	{
		int size = points.size();
		for(int x = 0; x<points.size(); x++)
		{
			for(int i=0; i<SIZE; i++)
			{
				for(int j=0; j<SIZE; j++)
				{
					Piece friendly = this.board1.getPiece(i, j);
					if(friendly.getSide().equals(side))
					{
						if(p.getType().equals(" Knight  ")||p.getType().equals("BK-Knight"))
						{
							if(friendly.movePossible(p.getX(), p.getY()))
							{
								return true;
							}
						}else if(friendly.getType().equals("   King  ")  &&  size==1)
						{
							return true;
						}else if(friendly.getType().equals("BK-->King")&&size==1)
						{
							return true;
						}else if(friendly.movePossible((int)points.get(x).getX(), (int)points.get(x).getY()) && !friendly.getType().equals("BK-->King") && !friendly.getType().equals("   King  "))
						{
							return true;
						}
					}
				
				}
			}
		}
		return false;
	}
	
	
	
	
	/**
	 * This method find the piece which is endangering the king
	 * 
	 * @param side - is the side of the king
	 * @return piece which is endangering the king
	 */
	public Piece findCheckingPiece(String side)
	{
		this.board1.getKing();
		Piece piece = new NullPiece(0,0,this.board1);
		for(int i=0; i<SIZE; i++)
		{
			for(int j=0; j<SIZE; j++)
			{
				piece = this.board1.getPiece(i, j);
				if(piece.getSide().equals("White")&&side.equals("Black"))
				{
					if(piece.movePossible(this.board1.bking.getX(), this.board1.bking.getY()))
					{
						return piece;
					}
				}else if(piece.getSide().equals("Black") && side.equals("White"))
				{
					if(piece.movePossible(this.board1.wking.getX(), this.board1.wking.getY()))
					{
						return piece;
					}
				}
			}
		}
		return piece;
	}
	
	
	
	
	/**
	 * This method get a piece and check if all pieces of one given side have atleast one possible move on the board.
	 * 
	 * @param side - side of the pieces which will be checked
	 * @return boolean true if a move is possible in one side, false if stalemate
	 */
	public boolean noMoreMove(String side)
	{
		for(int i=0; i<SIZE; i++)
		{
			for(int j=0; j<SIZE; j++)
			{
				Piece piece = this.board1.getPiece(i, j);
				if(piece.getSide().equals(side))
				{
					if(this.board1.moveAnywhereOnBoard(piece))
					{
						return false;
					}
				}
			}
		}
		return true;
	}
	
	
	
	
	
	/**
	 * if the piece pawn is on the far opposite block then it get to changed in to other pieces
	 * 
	 * @param p - location of the pawn
	 */
	public void pawnPromotion(int x, int y)
	{
		Piece temp = this.board1.getPiece(x, y);
		String input = "";
		System.out.println("Your Pawn has been promoted");
		System.out.println("Please select any piece it will be promoted to:");
		System.out.println("Rook/Knight/Bishop/Queen");
		try
		{
			input = bufferedreader.readLine();
		}catch(IOException IOerror)
		{
			System.out.println("Doesn't work");
		}
		if(temp.getSide().equals("White"))
		{
			if(input.equals("Queen")||input.equals("QUEEN")||input.equals("queen"))
			{
				Queen queen = new Queen(x, y, this.board1, "White");
				this.board1.add(queen);
			}else if(input.equals("Rook")||input.equals("ROOK")||input.equals("rook"))
			{
				Rook rook = new Rook(x, y, this.board1, "White");
				this.board1.add(rook);
			}else if(input.equals("Bishop")||input.equals("BISHOP")||input.equals("bishop"))
			{
				Bishop bishop = new Bishop(x, y, this.board1, "White");
				this.board1.add(bishop);
			}else if(input.equals("Knight")||input.equals("KNIGHT")||input.equals("knight"))
			{
				Knight knight = new Knight(x, y, this.board1, "White");
				this.board1.add(knight);
			}else if(input.equals(""))
			{
				Queen queen = new Queen(x, y, this.board1, "White");
				this.board1.add(queen);
			}else
			{
				Queen queen = new Queen(x, y, this.board1, "White");
				this.board1.add(queen);
			}
		}else
		{
			if(input.equals("Queen")||input.equals("QUEEN")||input.equals("queen"))
			{
				Queen queen = new Queen(x, y, this.board1, "Black");
				this.board1.add(queen);
			}else if(input.equals("Rook")||input.equals("ROOK")||input.equals("rook"))
			{
				Rook rook = new Rook(x, y, this.board1, "Black");
				this.board1.add(rook);
			}else if(input.equals("Bishop")||input.equals("BISHOP")||input.equals("bishop"))
			{
				Bishop bishop = new Bishop(x, y, this.board1, "Black");
				this.board1.add(bishop);
			}else if(input.equals("Knight")||input.equals("KNIGHT")||input.equals("knight"))
			{
				Knight knight = new Knight(x,y, this.board1, "Black");
				this.board1.add(knight);
			}else if(input.equals(""))
			{
				Queen queen = new Queen(x, y, this.board1, "Black");
				this.board1.add(queen);
			}else
			{
				Queen queen = new Queen(x, y, this.board1, "Black");
				this.board1.add(queen);
			}
		}
		this.board1.clearPromotion();
	}
	
	
	
	
	
	
	
	/**
     * Change the string to Point representation of the input
     * if the input is invalid then return Point(9,9) which is considered as invalid input.
     * @param s - string representation of the user input
     * @return A point representation of the input string.
     */
	public Point getPoints(String s)
	{
		if(s.length()==2)
		{
			int y = (int)s.charAt(1)-48;
			int x = (int)s.charAt(0)-48;
			if(x>7 || y>7)
			{
				System.out.println("Sorry, you have entered an invalid input");
				return new Point(9, 9);
				
			}else
			{
				return new Point(x, y);
			}
		}
		return new Point(9, 9);
	}
	
	
	
	
	
	/**
     * check if any of the item on the array is false and if it is then return false.
     * if all the items are true then return true.
     * @param bool - 2d array of boolean to represent the all coordinate on a board.
     * @return Boolean set to true if KNIGHT TOUR is a win

     */
	public boolean knightTour(boolean[][] bool)
	{
		for(int x=0; x<SIZE; x++)
		{
			for(int y=0; y<SIZE; y++)
			{
				if(bool[x][y]==false)
				{
					return false;
				}
			}
		}
		return true;
	}
	
	
	
	
	
	/**
	 * Compare if the two queens are the same or if this queen is already in use.
	 * 
	 * @param q - input a queen to compare with the other queens.
	 * @return Boolean set to true if the queen q and one other queen are equal
	 */
	public boolean compareQueen(Queen q)
	{
		for (int j=0; j<NUMBER_OF_QUEENS; j++)
		{
			if(q.getSide()=="White" && queens[j].getSide()=="White" && q.isEqual(queens[j]))
			{
				if(q.getX()==(queens[j].getX()) && q.getY()==(queens[j].getY()));
				{
					return true;
				}
			}
		}
		return false;
	}
	
	
	
	
	
	/** 
	 * Compare if any queen is in the way of another queen.
	 * @return Boolean set to true if they are endangering each other and false if they are not
	 */
	public boolean eightQueen()
	{
		for (int i=0; i<NUMBER_OF_QUEENS; i++)
		{
			Queen temp = this.queens[i];
			for(int j=0; j<NUMBER_OF_QUEENS; j++)
			{
				if(temp.isEqual(this.queens[j])!=true && this.queens[j].getSide()=="White" && temp.getSide()=="White")
				{
					if(temp.eightQueenMove(this.queens[j].getX(), this.queens[j].getY()))
					{
						return true;
					}
				}
			}
		}
		return false;
	}
}
